package com.bhprod.comatule.search;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ExpandableListView;
import android.widget.TextView;

import com.bhprod.comatule.MenuActivity;
import com.bhprod.comatule.R;
import com.bhprod.comatule.db.DBDataSource;
import com.bhprod.comatule.detail.SpeciesDetailActivity;
import com.bhprod.comatule.model.Taxon;
import com.bhprod.comatule.slideshow.SlideshowActivity;

/**
 * Activity for searching species by taxon
 * 
 * @author MonkeyKiki
 * 
 */
public class SearchByTaxonActivity extends Activity {

	private TaxonsListAdapter adapter;
	private int nbSelectedGroups = 0;
	private String nbGroupsSuffix;
	/** level 1 : taxon level, level 2 : taxon ids */
	private List<List<Integer>> taxonIdsByLevel = new ArrayList<List<Integer>>();
	private int taxonLevel = 0;
	private String taxonLevelPrefix;
	
	private static final int ID_PHOTO_ACTIVITY = 1;
	private static final int ID_DETAIL_ACTIVITY = 2;
	private static final int ID_LIST_ACTIVITY = 3;

	/**
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.search_group_list);

		ExpandableListView listView = (ExpandableListView) findViewById(R.id.groupsList);

		adapter = new TaxonsListAdapter(this);
		listView.setAdapter(adapter);

		// Get the initial list of taxons
		List<Taxon> rootTaxons = DBDataSource.getInstance().getTaxonsByParents(null);
		adapter.setTaxons(rootTaxons);
		adapter.notifyDataSetChanged();

		// Stock initial ids in level 1 list
		constructCurrentLevelTaxonList();

		updateNbGroups();

		taxonLevelPrefix = getString(R.string.taxon_level);
		updateTaxonLevel();
	}

	private void constructCurrentLevelTaxonList() {
		List<Taxon> taxons = adapter.getTaxons();
		List<Integer> taxonIds = new ArrayList<Integer>(taxons.size());
		for (Taxon taxon : taxons) {
			taxonIds.add(taxon.getId());
		}
		
		taxonIdsByLevel.add(taxonIds);
	}

	/**
	 * @see android.app.Activity#onBackPressed()
	 */
	@Override
	public void onBackPressed() {
		// First level, return to menu
		if (taxonLevel == 0) {
			Intent intent = new Intent(this, MenuActivity.class);
			startActivity(intent);
			finish();
		} else {
			taxonLevel--;

			// Load taxons from the previous level
			List<Taxon> taxons = DBDataSource.getInstance().getTaxonsByIds(taxonIdsByLevel
					.get(taxonLevel));

			adapter.setTaxons(taxons);
			adapter.notifyDataSetChanged();
			updateTaxonLevel();
			nbSelectedGroups = 0;
			updateNbGroups();
		}
	}

	/**
	 * Manage click on checkboxes
	 * 
	 * @param checkbox
	 *            The clicked checkbox
	 */
	public void checkGroup(View checkbox) {
		CheckBox cb = (CheckBox) checkbox;
		if (cb.isChecked()) {
			nbSelectedGroups++;
			adapter.getSelectedGroupPositionInCurrentLevel().add((Integer) cb.getTag());
		} else {
			nbSelectedGroups--;
			adapter.getSelectedGroupPositionInCurrentLevel().remove((Integer) cb.getTag());
		}
		updateNbGroups();
	}

	public void clickPhotoButton(View button) {
		if (adapter.getSelectedGroupPositionInCurrentLevel().size() <= 0) {
			return;
		}
		
		// Search selected species
		ArrayList<Integer> speciesIds = new ArrayList<Integer>();

		List<Taxon> taxons = adapter.getTaxons();

		for (Integer taxonPosition : adapter.getSelectedGroupPositionInCurrentLevel()) {
			speciesIds.addAll(getTaxonSpeciesIds(taxons.get(taxonPosition)));
		}

		Intent intent = new Intent(this, SlideshowActivity.class);
		Bundle b = new Bundle();
		b.putIntegerArrayList("speciesIds", speciesIds);
		intent.putExtras(b);
		startActivityForResult(intent, ID_PHOTO_ACTIVITY);
	}

	private List<Integer> getTaxonSpeciesIds(Taxon taxon) {
		List<Integer> ids = new ArrayList<Integer>();

		if (taxon.getNbSubTaxons() > 0) {
			List<Taxon> taxonChildren = DBDataSource.getInstance().getTaxonsByParent(taxon.getId());
			for (Taxon child : taxonChildren) {
				ids.addAll(getTaxonSpeciesIds(child));
			}
		} else if (taxon.getNbSubSpecies() > 0) {
			ids.addAll(DBDataSource.getInstance().getSpeciesIdsByTaxon(taxon.getId()));
		}

		return ids;
	}

	public void clickListButton(View button) {
		if (adapter.getSelectedGroupPositionInCurrentLevel().size() <= 0) {
			return;
		}
		
		List<Taxon> allTaxons = adapter.getTaxons();
		int nbSelectedTaxons = adapter.getSelectedGroupPositionInCurrentLevel().size();
		List<Taxon> selectedTaxons = new ArrayList<Taxon>(nbSelectedTaxons);
		int nbTaxonsWithSubTaxons = 0;

		for (Integer taxonPosition : adapter.getSelectedGroupPositionInCurrentLevel()) {
			Taxon taxon = allTaxons.get(taxonPosition);
			selectedTaxons.add(taxon);
			if (taxon.getNbSubTaxons() > 0) {
				nbTaxonsWithSubTaxons++;
			}
		}

		// 1. All taxons have subtaxons : display all subtaxons
		if (nbSelectedTaxons == nbTaxonsWithSubTaxons) {
			List<Integer> selectedTaxonIds = new ArrayList<Integer>(nbSelectedTaxons);
			for (Taxon taxon : selectedTaxons) {
				selectedTaxonIds.add(taxon.getId());
			}
			List<Taxon> subTaxonsList = DBDataSource.getInstance().getTaxonsByParents(selectedTaxonIds);
			adapter.setTaxons(subTaxonsList);
			adapter.notifyDataSetChanged();
			taxonLevel++;
			updateTaxonLevel();
			nbSelectedGroups = 0;
			updateNbGroups();
			constructCurrentLevelTaxonList();
		}
		// 2. Not all taxons have subtaxons : display subtaxons and taxons which
		// don't have subtaxons
		else if (nbTaxonsWithSubTaxons > 0) {
			List<Taxon> newTaxonsList = new ArrayList<Taxon>();

			for (Taxon taxon : selectedTaxons) {
				if (taxon.getNbSubTaxons() > 0) {
					newTaxonsList.addAll(DBDataSource.getInstance().getTaxonsByParent(taxon.getId()));
				} else {
					newTaxonsList.add(taxon);
				}
			}
			adapter.setTaxons(newTaxonsList);
			adapter.notifyDataSetChanged();
			taxonLevel++;
			updateTaxonLevel();
			nbSelectedGroups = 0;
			updateNbGroups();
			constructCurrentLevelTaxonList();
		}
		// 3. taxons have no subtaxons, just subspecies : display species list or detail
		else {
			// Search selected species
			ArrayList<Integer> speciesIds = new ArrayList<Integer>();

			for (Taxon taxon : selectedTaxons) {
				speciesIds.addAll(getTaxonSpeciesIds(taxon));
			}

			// Only one species selected : display its details
			if (speciesIds.size() == 1) {
				Intent intent = new Intent(this, SpeciesDetailActivity.class);
				Bundle b = new Bundle();
				b.putInt("speciesId", speciesIds.get(0));
				intent.putExtras(b);
				startActivityForResult(intent, ID_DETAIL_ACTIVITY);
			}
			// Many species selected : display the species list
			else {
				Intent intent = new Intent(this, SearchBySpeciesActivity.class);
				Bundle b = new Bundle();
				b.putIntegerArrayList("speciesIds", speciesIds);
				intent.putExtras(b);
				startActivityForResult(intent, ID_LIST_ACTIVITY);
			}
		}
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	}

	/**
	 * Update the displayed number of selected groups
	 */
	private void updateNbGroups() {
		if (taxonLevel == 0) {
			nbGroupsSuffix = getString(R.string.nb_selected_taxons);
		} else {
			nbGroupsSuffix = getString(R.string.nb_selected_subtaxons);
		}

		TextView nbGroups = (TextView) findViewById(R.id.nbGroups);
		nbGroups.setText(Integer.toString(nbSelectedGroups) + " "
				+ nbGroupsSuffix);
	}

	/**
	 * Update the displayed level in taxons hierarchy
	 */
	private void updateTaxonLevel() {
		TextView level = (TextView) findViewById(R.id.listLevel);
		level.setText(taxonLevelPrefix + " " + Integer.toString(taxonLevel + 1));
	}

}
